/*********************************************************************************
 *      Copyright:  (C) 2025 iot25<lingyun@email.com>
 *                  All rights reserved.
 *
 *       Filename:  client_main.c
 *    Description:  This file client_main
 *                 
 *        Version:  1.0.0(02/05/25)
 *         Author:  iot25 <lingyun@email.com>
 *      ChangeLog:  1, Release initial version on "02/05/25 14:52:09"
 *                 
 ********************************************************************************/
#include<stdio.h>
#include<getopt.h>
#include<time.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<stdlib.h>
#include<sqlite3.h>

#include"client_main.h"
#include"get_ds18b20_detals.h"
#include"logger.h"
#include"client_connect_sever.h"
#include"get_time.h"
#include"judge_connect.h"
#include"send_data_to_server.h"
#include"pack_data.h"
#include"sqlite_database.h"

#define _LOG_FILENAME_ "logger.log"
#define _LOG_LOCK_		1

void print_help_usage()
{
    printf("\nOptions:\n");
    printf("-h, --help\t\tPrint usage information\n");
    printf("-a, --address\t\tServer IP address\n");
    printf("-p, --port\t\tServer port\n");
    printf("-d, --debug\t\tOutput print on screen\n");
	printf("-i, --interval\t\tSample interval in seconds\n");
}


 
int main(int argc, char *argv[])
{
	sqlite3    				 *db;
	char					log_file[16] = "logger.log"; 
	int						sample_flag = 0;
	int						rv = 0;
	char					*db_name = "ds18b20_datas";
	char					data[1024] = {0};
	int						data_len;
	int						opt;
	int						option_index = 0;
	int						sample_interval = 1800;
	char 					device_id[32];
	pack_t					pack;
	socket_t				sock;
	char					*hostname = NULL;
	int						port;
	struct option 			long_option[] = 
	{
		{"help", no_argument, 0, 'h'},
		{"address", required_argument, 0, 'a'},
		{"port", required_argument, 0, 'p'},
		{"debug", required_argument, 0, 'd'},
		{"interval", required_argument, 0, 'i'},
		{NULL, 0, NULL, 0}
	};

	//解析命令行参数
	while((opt = getopt_long(argc, argv, "ha:p:i:", long_option, &option_index)) != -1)
	{
		switch(opt)
		{
			case'h':
				print_help_usage();
				return 0;

			case'a':
				hostname = optarg;
				break;

			case'd':
				strcpy(log_file, "console");
				break;

			case'p':
				port = atoi(optarg);
				break;

			case'i':
				sample_interval =atoi(optarg);
				break;

			default:
				print_help_usage();
				return -1;
		}
	}
	if( (!hostname) || (!port) )            /* 判断输入参数是否合法 */
	{
		print_help_usage();               /* 打印帮助信息 */
		return 0;
	}
 	printf("socket[%s:%d]\n", hostname, port);
	

	//启动日志文件
	 log_open(_LOG_FILENAME_, LOG_LEVEL_DEBUG, 1024, _LOG_LOCK_);

	//网络初始化
	if(socket_init(&sock, hostname, port) != 0)
	{
		log_error("Socket initialization failure!\n");
		return -1;
	}

	//创建数据库
	if((create_db(db_name, db) < 0))
	{
		log_error("Creat table ds18b20 error: %s\n", strerror(errno));
		return -1;
	}

	//工作的主循环
	time_t last_time = 0;
	while(1)
	{
		sample_flag = 0;
		time_t cur_time = time(NULL);
		if((difftime(cur_time, last_time)) > sample_interval)
		{
			memset(&pack, 0, sizeof(pack_t));
			printf("time_interval: %d\n", sample_interval);
			if(get_temperature(&pack.temperature) == 0)
			{
				log_debug("Temp: %f\n", pack.temperature);
				
				get_devid(device_id, sizeof(device_id));
				strncpy(pack.dev_id, device_id, sizeof(pack.dev_id));
				log_debug("Get device_id is: %s\n", pack.dev_id);
				
				if((rv = get_time(pack.dev_time, sizeof(pack.dev_time)))== 0)
				{
					log_debug("Current time: %s\n", pack.dev_time);
				}
				else
				{
					log_error("get time failure: %s\n", strerror(errno));
				}
				last_time =time(NULL);
				sample_flag = 1;
			}
		}

		//在采完样之后先判断是不是连上了
		if( judge_connect(&sock) <  0 )		//说明连接失败了
		{
			if( client_connect_server(&sock) != 0 )
			{
				log_error("Socket client connect again failure\n");
				log_debug("client_fd :%d\n", sock.fd);
				if(sample_flag == 1)
				{
					if((rv = insert_data(db, &pack)) < 0)
					{
                		log_error("insert_data failure: %s\n", strerror(errno));
					}
					printf("insert_data successfully!\n");
					sample_flag = 0;
				}
				continue;
			}
			log_debug("Socket client connect again successfully!\n");
		}	

		/*是正常连接上的情况要做两件事：
		 * 1.数据库里没有数据正常传输,并且如果在传输过程中出现问题了及时上传到数据库
		 * 2.有数据需要上传后上传数据库里的消息
		 */
		if(sample_flag == 1)
		{
			if(sock.fd> 0)
			{
				//pack_data
			//	data_len = pack_data(&pack, data, sizeof(data));
			//	data_len = pack_tlv(&pack, (uint8_t *)data, sizeof(data));
				data_len = pack_data_json(&pack, data, sizeof(data));
				if(data_len > 0)
				{
					if(send_data_to_server(sock.fd, data) < 0)
					{
						if((rv = insert_data(db, &pack)) < 0)
						{ 
							log_error("insert_data failure: %s\n",strerror(errno));
						}
						printf("insert_data successfully!\n");
						sample_flag = 0;
						continue;
					}
					else
					{
						log_debug("Pack and Send data successfully!\n");
						sample_flag = 0;
						continue;
					}
				}
				else
				{
					log_debug("Pack_data failure: %s\n",strerror(errno));
				}
			}
		}

		//再不采样的但是连接成功的时候可以进行数据库中数据的传输
		if((rv = is_table_empty(db)) == 1)
		{
			if(sock.fd > 0)
			{
				get_db_record(db, &pack);
				data_len = pack_data(&pack, data, sizeof(data));
				if( data_len > 0 )
				{
					if( !(send_data_to_server(sock.fd, data)) )  
					{
						delete_dbdata(db);
						continue;
					}
				}
				else
				{
					log_debug("Pack_data failure: %s\n",strerror(errno));
				}
			}
		}

		usleep(100000);
	}
		close(sock.fd);
		sqlite3_close(db);
		log_close();

		return 0;
}
